home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0992.ARJ / DBINT9.ASM < prev    next >
Assembly Source File  |  1992-06-10  |  29KB  |  1,341 lines

  1. ;dbint9.asm 
  2. ;Keyboard ISR for debugger                 
  3. ;
  4. .386P
  5. ;---------------------------------------------------------------------------- 
  6. ;Copyright 1991, 1992 ASMicro Co. 
  7. ;3/1/92       Scott Schaefer and Rick Knoblaugh
  8. ;-----------------------------------------------------------------------------
  9. ;
  10. ;The code is table-driven, rather than the customary IF ... THEN ... ELSE type
  11. ;code typically seen.  This makes the code somewhat faster for 
  12. ;typical keys, and a lot faster for some.  
  13. ;
  14. ;Of course, the standard tradeoff of size vs. speed causes it to 
  15. ;be somewhat larger.  It also has a couple of warts where some of
  16. ;the esoteric exceptions could not reasonably be handled according
  17. ;to the table-driven philosophy.
  18. ;
  19. ;Note that some of the key combinations which normally generate
  20. ;"internal" requests are not implemented (i.e. they are "dummied").
  21. ;Where these key combinations are recognized, the default action 
  22. ;is commented-out, and a comment inserted which is enclosed in 
  23. ;"<<< ... >>>" characters.
  24. ;
  25. ;Also, the INT 15, Keyboard Intercept (AH=4F) function is NOT called.
  26. ;
  27. ;Finally, the some BIOS docs state that their INT 9 "... places the 
  28. ;value F0h in the low byte character code position for some 
  29. ;Alt/character key combinations ...".  This code does not do 
  30. ;this -- since the standard INT 16 strips it anyway ....
  31. ;
  32. ;-----------------------------------------------------------------------------
  33.                 include dbequ.inc
  34.                 include dbstruc.inc
  35.  
  36. data            segment para public 'data16' use16
  37.                 extrn   buf_put:word
  38.                 extrn   buf_get:word, key_buf:byte
  39.  
  40. BUF_START       equ     offset key_buf
  41. BUF_END         equ     offset buf_put
  42.  
  43. data            ends
  44.  
  45. ;================
  46. ;In order to link with test program that simulates make/break codes,
  47. ;set this to some value; otherwise, leave it commented.
  48. ;================
  49.  
  50. ;;LINK_CPP_TEST    EQU    1
  51.  
  52. ;================
  53. ;In order to run as real INT 9, but w/o debugger, set this to some 
  54. ;value; otherwise, leave it commented.
  55. ;================
  56.  
  57. ;;;;;STANDALONE_TEST    EQU    1
  58.  
  59. ;================
  60. ;I/O PORTS
  61. ;================
  62.  
  63. IO_KB_DATA    EQU    60H
  64. IO_KB_8042    EQU    64H
  65. _8042_IBUF_FULL    EQU    20H
  66.  
  67.  
  68. IO_PIC        EQU    20H
  69. _EOI        EQU    20H
  70.  
  71.  
  72. ;================
  73. ;8042 commands
  74. ;================
  75.  
  76. KB_8042_RESEND        EQU    0FEH
  77. KB_8042_ACK        EQU    0FAH
  78.  
  79. KB_8042_DISABLE        EQU    0ADH
  80. KB_8042_ENABLE        EQU    0AEH
  81. KB_8042_NEWLED        EQU    0EDH
  82. KB_8042_CLR_REENABLE    EQU    0F4H
  83.  
  84.  
  85. DISABLE_KB    MACRO
  86.     LOCAL    KBOPEN
  87.  
  88.     CALL    WAIT_8042_ACCEPTED    ;WAIT FOR OPEN LINE TO 8042
  89.     JNZ    KBOPEN
  90.     MOV    AL,KB_8042_DISABLE    ;DISABLE INTERFACE 
  91.     OUT    IO_KB_8042,AL
  92.     STI
  93.  
  94. KBOPEN:
  95. ENDM
  96.  
  97. ENABLE_KB    MACRO
  98.     LOCAL    KBOPEN
  99.  
  100.     CALL    WAIT_8042_ACCEPTED    ;WAIT FOR OPEN LINE TO 8042
  101.     JNZ    KBOPEN
  102.     MOV    AL,KB_8042_ENABLE    ;ENABLE INTERFACE
  103.     OUT    IO_KB_8042,AL
  104.     STI
  105.  
  106. KBOPEN:
  107. ENDM
  108.  
  109. ;==============================
  110. ;    BIOS DATA AREA VALUES
  111. ;==============================
  112.  
  113. BIOS_DATA  SEGMENT use16 AT 40H
  114.  
  115. ORG 17H
  116. BIOS_KB_SHIFT_FLAGS    DB    ?
  117. BIOS_EXTKB_SHIFT_FLAGS    DB    ?
  118.  
  119. ORG 1AH
  120. BIOS_KB_BUFPTR        DW    ?
  121. BIOS_KB_BUFHEAD        DW    ?
  122. BIOS_KB_BUFFER        DW    16 DUP(?)
  123.  
  124. ORG 71H
  125. BIOS_KB_CTRLBRK_FLAG    DB    ?
  126. BIOS_KB_SOFTBOOT_FLAG    DW    ?
  127.  
  128. ORG 80H
  129. BIOS_KB_EXTBUFHEAD    DW    ?
  130. BIOS_KB_EXTBUFEND    DW    ?
  131.  
  132. ORG 96H
  133. BIOS_KB_EXTSTAT_1    DB    ?
  134. BIOS_KB_EXTSTAT_2    DB    ?
  135.  
  136. BIOS_DATA  ENDS
  137.  
  138.  
  139. ;
  140. ;================
  141. ;Bits in BIOS_KB_SHIFT_FLAGS
  142. ;================
  143.  
  144. INS_ACTIVE    EQU    80H
  145. CAPSLK_ACTIVE    EQU    40H
  146. NUMLK_ACTIVE    EQU    20H
  147. SCRLK_ACTIVE    EQU    10H
  148.  
  149. ALT_PRESSED    EQU     8
  150. CTRL_PRESSED    EQU     4
  151. LSHIFT_PRESSED    EQU     2
  152. RSHIFT_PRESSED    EQU     1
  153.  
  154.  
  155. ;================
  156. ;Bits in BIOS_EXTKB_SHIFT_FLAGS
  157. ;================
  158.  
  159. INS_PRESSED    EQU    80H
  160. CAPSLK_PRESSED    EQU    40H
  161. NUMLK_PRESSED    EQU    20H
  162. SCRLK_PRESSED    EQU    10H
  163.  
  164. PAUSE_ACTIVE    EQU     8
  165. SYSREQ_PRESSED    EQU     4
  166. LALT_PRESSED    EQU     2
  167. LCTRL_PRESSED    EQU     1
  168.  
  169.  
  170. ;================
  171. ;Bits in BIOS_KB_EXTSTAT_1
  172. ;================
  173.  
  174. READID_INPROG    EQU    80H
  175. LASTCODE_ID1    EQU    40H
  176. NUMLK_FORCED    EQU    20H
  177. EXT_KEYBOARD    EQU    10H
  178.  
  179. RALT_ACTIVE    EQU     8
  180. RCTRL_ACTIVE    EQU     4
  181. LASTCODE_E0    EQU     2
  182. LASTCODE_E1    EQU     1
  183.  
  184.  
  185. ;================
  186. ;Bits in BIOS_KB_EXTSTAT_2
  187. ;================
  188.  
  189. ERRFLAG_KBCMD    EQU    80H
  190. LEDUPD_INPROG    EQU    40H
  191. RESEND_FROM8042 EQU    20H
  192. ACK_FROM8042     EQU    10H
  193.  
  194. ;        EQU     8
  195. CAPSLK_LED    EQU     4
  196. NUMLK_LED    EQU     2
  197. SCRLK_LED    EQU     1
  198.  
  199.  
  200. ;
  201. ;================
  202. ;Values used by the ISR
  203. ;================
  204.  
  205. BREAK_CODE    EQU    80H
  206. CTRL_PRSTC    EQU    7200H        ;SPECIAL SCAN CODE FOR START/STOP PRINT
  207.  
  208. ;-------------------
  209. ; Handler types
  210. ;-------------------
  211. NORM        EQU    1
  212. NORM_CA0        EQU    2
  213. FNKEY        EQU    3
  214. NUMPAD        EQU     4
  215. SPACEKEY        EQU    5
  216. SLASHKEY        EQU    6
  217. SYSKEY        EQU     7
  218. PRTSCKEY    EQU     8    
  219. TOGGLEKEY    EQU    9
  220. SHIFTKEY    EQU    10
  221. TWOPART        EQU    11
  222. ACK_RXCODE    EQU    12
  223. RESEND_RXCODE    EQU    13
  224. OVERRUN_RXCODE    EQU    14
  225.  
  226.  
  227. EXITS_PAUSE    EQU    TOGGLEKEY     ;KEYS < THIS, ALWAYS EXIT PAUSE STATE
  228.  
  229. CTRL_INVALID    EQU    0FFH        ;WHEN <CTRL>-KEY IS INVALID
  230.  
  231. BEEP_NOCODE    EQU    0FCH
  232. NOCODE_PICRESET    EQU    0FDH
  233. NEW_PAUSE_RQ    EQU    0FEH
  234. STORE_NOCODE    EQU    0FFH
  235.  
  236.  
  237.  
  238. ;
  239. IFDEF LINK_CPP_TEST
  240. _TEXT    SEGMENT BYTE PUBLIC 'CODE' use16
  241.     ASSUME CS:_TEXT
  242.  
  243.     PUBLIC    _lastkey
  244.     PUBLIC    _int9_test_entry
  245.  
  246. KBBUF    DW    0
  247.  
  248. _lastkey:
  249.     MOV    AX,CS:KBBUF
  250.     RET
  251.  
  252. _int9_test_entry:
  253.     MOV    CS:KBBUF,0
  254.     JMP    NEAR PTR KB_ISR
  255. ELSE
  256. IFDEF STANDALONE_TEST
  257. _TEXT    SEGMENT BYTE PUBLIC 'CODE' use16
  258.     ASSUME CS:_TEXT
  259. ELSE
  260. zcode    segment para public 'code16' use16
  261.  
  262.                 public  int_9_isr                
  263. ENDIF
  264. ENDIF
  265.     
  266.     ASSUME CS:zcode, DS:NOTHING, ES:NOTHING, SS:NOTHING
  267.  
  268. ;---------------------------
  269. ;"handler()" vectors
  270. ;
  271. ;This table MUST be in order according 
  272. ;to the 'Handler types' equates above
  273. ;---------------------------
  274.  
  275. JUMP_TAB    LABEL    WORD
  276.     DW    NORM_HANDLER
  277.     DW    TAB_HANDLER
  278.     DW    FNKEY_HANDLER
  279.     DW    NUMPAD_HANDLER
  280.     DW    SPACE_HANDLER
  281.     DW    SLASH_HANDLER
  282.     DW    SYS_HANDLER
  283.     DW    PRTSC_HANDLER
  284.     DW    TOGGLEKEY_HANDLER
  285.     DW    SHIFTKEY_HANDLER 
  286.     DW    TWOPART_HANDLER
  287.     DW    ACK_HANDLER
  288.     DW    RESEND_HANDLER
  289.     DW    OVERRUN_HANDLER
  290.  
  291. ;---------------------------
  292. ;Which translate table to use based upon shift state is determined 
  293. ;by this array.  'BIOS_KB_SHIFT_FLAGS' word is manipulated to produce:
  294. ;    Bit 0:Shift
  295. ;    Bit 1:Ctrl
  296. ;    Bit 2:Alt
  297. ;The result, 0-7 is used to index the table.
  298. ;
  299. ;Note tha values prioritize simultaneous multiple shift states as:
  300. ;    Highest: Alt
  301. ;    Middle: Ctrl
  302. ;    Lowest: Shift
  303. ;---------------------------
  304.  
  305. SHIFT_TABLES    LABEL    WORD
  306.     DW    OFFSET UNSHIFTED_XLAT_TAB    ;NO SHIFTS
  307.     DW    OFFSET SHIFTED_XLAT_TAB        ;EITHER SHIFT = 1
  308.     DW    OFFSET CTRL_XLAT_TAB        ;CTRL
  309.     DW    OFFSET CTRL_XLAT_TAB        ;CTRL+SHIFT (CTRL > PRIORITY)
  310.     DW    OFFSET ALT_XLAT_TAB        ;ALT HIGHEST PRIORITY OF ALL
  311.     DW    OFFSET ALT_XLAT_TAB
  312.     DW    OFFSET ALT_XLAT_TAB
  313.     DW    OFFSET ALT_XLAT_TAB
  314.  
  315.  
  316. ;---------------------------
  317. ;Each of the next five tables is indexed via scan code.
  318. ;
  319. ;This first table returns an index into the JUMP_TAB table to 
  320. ;vector to the proper key-handler.
  321. ;
  322. ;Note that this table is index via raw scan code; almost all values > 127
  323. ;return 0 since these are "break" codes.
  324. ;---------------------------
  325.  
  326. JUMPTAB_INDEX    DB    OVERRUN_RXCODE  ;OVERRUN SCANCODE (SOME DOCS)
  327.         DB    NORM        ;<Esc>
  328.         DB    12 DUP(NORM)    ;"1!" through "=+"
  329.         DB    NORM        ;<BS>
  330.         DB    NORM_CA0    ;<TAB>
  331.         DB    12 DUP(NORM)    ;"Q" through "]"
  332.         DB    NORM        ;<Enter>        
  333.         DB    SHIFTKEY        
  334.         DB    9 DUP(NORM)    ;"A" through "L"
  335.         DB    3 DUP(NORM)    ;";:", "'"", and "`~"                
  336.         DB    SHIFTKEY
  337.         DB    NORM        ;"\|"
  338.         DB    7 DUP(NORM)    ;"Z" through "M"
  339.         DB    2 DUP(NORM)    ;",<", ".>"
  340.         DB    SLASHKEY    ;"/?", KEYPAD SLASH IF E0
  341.         DB    SHIFTKEY
  342.         DB    PRTSCKEY    ;E0-PRTSC, ELSE ASTERISK JUST LIKE TAB
  343.         DB    SHIFTKEY
  344.         DB    SPACEKEY    ;SPACE BAR    
  345.         DB    TOGGLEKEY    ;CAPSLOCK
  346.         DB    10 DUP(FNKEY)    ;F1-F10        
  347.         DB    TOGGLEKEY    ;NUMLOCK
  348.         DB    TOGGLEKEY    ;SCROLLOCK
  349.         DB    3 DUP(NUMPAD)
  350.         DB    NORM_CA0    ;KEYPAD -
  351.         DB    3 DUP(NUMPAD)
  352.         DB    NORM_CA0    ;KEYPAD +
  353.         DB    5 DUP(NUMPAD)
  354.         DB    SYSKEY        ;SCAN CODE 54H
  355.         DB    0        ;SCAN CODE 55H
  356.         DB    NORM
  357.         DB    2 DUP(FNKEY)    ;F11-F12
  358.         DB    80H - ($ - JUMPTAB_INDEX) DUP(0)
  359.  
  360. ;BREAK KEYS START HERE
  361.         DB    29 DUP(0)        
  362.         DB    SHIFTKEY        
  363.         DB    12 DUP(0)        
  364.         DB    SHIFTKEY        
  365.         DB    11 DUP(0)        
  366.         DB    SHIFTKEY        
  367.         DB    0
  368.         DB    SHIFTKEY        
  369.         DB    0
  370.         DB    TOGGLEKEY    ;CAPSLOCK
  371.         DB    10 DUP(0)
  372.         DB    TOGGLEKEY    ;NUMLOCK
  373.         DB    TOGGLEKEY    ;SCROLLOCK
  374.         DB    0E0H - ($ - JUMPTAB_INDEX) DUP(0)
  375.         DB    TWOPART
  376.         DB    TWOPART
  377.         DB    KB_8042_ACK - ($ - JUMPTAB_INDEX) DUP(0)
  378.         DB    ACK_RXCODE
  379.         DB    0,0,0 
  380.         DB    RESEND_RXCODE
  381.         DB    OVERRUN_RXCODE     ;OVERRUN SCANCODE (SOME OTHER DOCS)
  382.  
  383.  
  384.  
  385. ;
  386. ;---------------------------
  387. ;The remaining four tables comprise the translate tables.
  388. ;Note each of these tables need only contain entries for codes
  389. ;which we actually translate; since the only break codes we care
  390. ;about (non-zero entires in JUMPTAB_INDEX) don't get translated,
  391. ;these tables need only have entries for codes 0-58H.
  392. ;---------------------------
  393. UNSHIFTED_XLAT_TAB    LABEL    BYTE
  394.     DB    0
  395.     DB    1BH
  396.  
  397.     DB    "1234567890-="
  398.     DB    8,9        ;BS, TAB
  399.  
  400.     DB     "qwertyuiop[]"
  401.     DB    0DH        ;ENTER
  402.     DB    CTRL_PRESSED     ;<CTRL>
  403.  
  404.     DB    "asdfghjkl;"
  405.     DB    39        ;SINGLE QUOTE
  406.     DB    "`"
  407.     DB    LSHIFT_PRESSED    ;LEFT <SHIFT>
  408.     DB    5CH
  409.  
  410.     DB    "zxcvbnm,./"
  411.     DB    RSHIFT_PRESSED    ;RIGHT <SHIFT>
  412.     DB    "*"    
  413.     DB    ALT_PRESSED    ;<ALT>
  414.     DB    " "        ;SPACE BAR    
  415.     DB    CAPSLK_PRESSED    ;CAPSLOCK
  416.     
  417.     DB    10 DUP(0)    ;UNSHIFTED FN KEY ( += SCAN CODE)
  418.     DB    NUMLK_PRESSED    ;NUMLOCK
  419.     DB    SCRLK_PRESSED    ;SCROLLOCK
  420.  
  421.     DB    47H,48H,49H
  422.     DB    "-"
  423.     DB    4BH,4CH,4DH
  424.     DB    "+"
  425.     DB    4FH,50H,51H,52H,53H
  426.     DB    0,0        ;SCAN CODE 54H, 55H
  427.     DB    5CH
  428.  
  429.     DB    2 DUP(85H-57H)    ;UNSHIFTED F11-F12 ( += SCAN CODE)
  430.  
  431.  
  432. ;
  433. SHIFTED_XLAT_TAB    LABEL    BYTE
  434.     DB    0
  435.     DB    1BH
  436.  
  437.     DB    "!@#$%^&*()_+"
  438.     DB    8        ;BS
  439.     DB    0        ;SHIFT-TAB GETS 0 IN LOW BYTE
  440.  
  441.     DB     "QWERTYUIOP{}"
  442.     DB    0DH        ;ENTER
  443.     DB    CTRL_PRESSED    ;<CTRL>
  444.  
  445.     DB    "ASDFGHJKL:"
  446.     DB    34        ;DOUBLE QUOTE
  447.     DB    "~"
  448.     DB    LSHIFT_PRESSED    ;LEFT <SHIFT>
  449.     DB    7CH
  450.     
  451.     DB    "ZXCVBNM<>?"
  452.     DB    RSHIFT_PRESSED    ;RIGHT <SHIFT>
  453.     DB    "*"    
  454.     DB    ALT_PRESSED    ;<ALT>
  455.     DB    " "        ;SPACE BAR    
  456.     DB    CAPSLK_PRESSED    ;CAPSLOCK
  457.     
  458.     DB    10 DUP(54H-3BH)    ;SHIFTED FN KEY    ( += SCAN CODE )
  459.     DB    NUMLK_PRESSED    ;NUMLOCK
  460.     DB    SCRLK_PRESSED    ;SCROLLOCK
  461.  
  462.     DB    "789"        ;NUMPAD ENTRIES
  463.     DB    "-"
  464.     DB    "456"        ;NUMPAD ENTRIES
  465.     DB    "+"
  466.     DB    "1230."        ;NUMPAD ENTRIES
  467.     DB    0,0        ;SCAN CODE 54H, 55H
  468.     DB    7CH
  469.     
  470.     DB    2 DUP(87H-57H)    ;SHIFTED F11-F12 ( += SCAN CODE)
  471.  
  472.     
  473. ;
  474. CTRL_XLAT_TAB        LABEL    BYTE
  475.     DB    0
  476.     DB    1BH        ;CTRL-ESC STILL 1B IN LOW BYTE
  477.     DB    CTRL_INVALID    ;CTRL-1 INVALID
  478.     DB    0        ;CTRL-2 GETS 0 IN LOW BYTE
  479.     DB    CTRL_INVALID    ;CTRL-3/4/5 INVALID
  480.     DB    2 DUP(CTRL_INVALID)
  481.     DB    1EH        ;CTRL-6 GETS 1EH IN LOW BYTE
  482.     DB    CTRL_INVALID    ;CTRL-7/8/9/0 INVALID
  483.     DB    3 DUP(CTRL_INVALID)
  484.     DB    1FH        ;CTRL-DASH GETS 1EH IN LOW BYTE
  485.     DB    CTRL_INVALID    ;CTRL-EQUALS INVALID
  486.     DB    7FH        ;CTRL-BS IS TREATED AS ASCII DEL
  487.     DB    94H        ;CTRL-TAB
  488.  
  489.     DB    'Q' - 'A' + 1
  490.     DB    'W' - 'A' + 1
  491.     DB    'E' - 'A' + 1
  492.     DB    'R' - 'A' + 1
  493.     DB    'T' - 'A' + 1
  494.     DB    'Y' - 'A' + 1
  495.     DB    'U' - 'A' + 1
  496.     DB    'I' - 'A' + 1
  497.     DB    'O' - 'A' + 1
  498.     DB    'P' - 'A' + 1
  499.  
  500.     DB    1BH, 1DH
  501.     DB    0AH        ;CTRL-ENTER TREATED AS ASCII LF
  502.     DB    CTRL_PRESSED    ;<CTRL>
  503.  
  504.     DB    'A' - 'A' + 1
  505.     DB    'S' - 'A' + 1
  506.     DB    'D' - 'A' + 1
  507.     DB    'F' - 'A' + 1
  508.     DB    'G' - 'A' + 1
  509.     DB    'H' - 'A' + 1
  510.     DB    'J' - 'A' + 1
  511.     DB    'K' - 'A' + 1
  512.     DB    'L' - 'A' + 1
  513.     DB    3 DUP(CTRL_INVALID)    ;CTRL-";","'", AND "`" INVALID
  514.  
  515.     DB    LSHIFT_PRESSED    ;LEFT <SHIFT>
  516.     DB    1CH
  517.  
  518.     DB    'Z' - 'A' + 1
  519.     DB    'X' - 'A' + 1
  520.     DB    'C' - 'A' + 1
  521.     DB    'V' - 'A' + 1
  522.     DB    'B' - 'A' + 1
  523.     DB    'N' - 'A' + 1
  524.     DB    'M' - 'A' + 1
  525.     DB    3 DUP(CTRL_INVALID)    ;CTRL-",",".", AND "/" INVALID
  526.     
  527.     DB    RSHIFT_PRESSED    ;RIGHT <SHIFT>
  528.     DB    96H        ;CTRL-*
  529.     DB    ALT_PRESSED    ;<ALT>
  530.     DB    " "        ;CTRL-SPACE TREATED IN HANDLER    
  531.     DB    CAPSLK_PRESSED    ;CAPSLOCK
  532.  
  533.     DB    10 DUP(5EH-3BH)    ;CTRL-FN KEY ( += SCAN CODE )
  534.     DB    PAUSE_ACTIVE    ;NUMLOCK
  535.     DB    SCRLK_PRESSED    ;SCROLLOCK
  536.  
  537.     DB    77H        ;NUMPAD ENTRIES
  538.     DB    8DH
  539.     DB    84H
  540.     DB    8EH        ; -
  541.     DB    73H
  542.     DB    8FH
  543.     DB    74H
  544.     DB    90H        ; +
  545.     DB    75H
  546.     DB    91H
  547.     DB    76H
  548.     DB    92H
  549.     DB    93H
  550.  
  551.     DB    0,0        ;SCAN CODE 54H, 55H
  552.     DB    CTRL_INVALID
  553.  
  554.     DB    2 DUP(89H-57H)    ;<CTRL> F11-F12 ( += SCAN CODE)
  555.  
  556.  
  557. ;
  558. ALT_XLAT_TAB    LABEL    BYTE
  559.     DB    0
  560.     DB    1
  561.     DB    78H,79H,7AH,7BH,7CH,7DH,7EH,7FH
  562.     DB    80H,81H,82H,83H
  563.     DB    0EH
  564.     DB    0A5H        ;ALT-TAB
  565.     DB    10H,11H,12H,13H,14H,15H,16H,17H
  566.     DB    18H,19H,1AH,1BH,1CH
  567.     DB    CTRL_PRESSED    ;<CTRL>
  568.     DB    1EH,1FH
  569.     DB    20H,21H,22H,23H,24H,25H,26H,27H
  570.     DB    28H,29H
  571.     DB    LSHIFT_PRESSED    ;LEFT <SHIFT>
  572.     DB    2BH,2CH,2DH,2EH,2FH
  573.     DB    30H,31H,32H,33H,34H,35H
  574.     DB    RSHIFT_PRESSED    ;RIGHT <SHIFT>
  575.     DB    37H        ;ALT-*
  576.     DB    ALT_PRESSED    ;<ALT>
  577.     DB    " "        ;ALT-SPACE BAR TREATED IN HANDLER
  578.     DB    CAPSLK_PRESSED    ;CAPSLOCK
  579.     DB    10 DUP(68H-3BH)    ;ALT-FN KEY ( += SCAN CODE )
  580.     DB    PAUSE_ACTIVE    ;NUMLOCK
  581.     DB    SCRLK_PRESSED    ;SCROLLOCK
  582.     DB    97H,98H,99H    ;SEPARATE KEYS (E0 SCAN)    
  583.     DB    4AH        ; -
  584.     DB    9BH
  585.     DB    0        ;NO SEPARATE KEY FOR <5>
  586.     DB    9DH
  587.     DB    4EH        ; +
  588.     DB    9FH,0A0H,0A1H,0A2H,0A3H
  589.     DB    0,0        ;SCAN CODE 54H, 55H
  590.     DB    CTRL_INVALID
  591.     DB    2 DUP(8BH-57H)    ;<ALT> F11-F12 ( += SCAN CODE)
  592.  
  593.  
  594. ALTBYTE    DB    0    ;BUILDING VALUE WITH <ALT>-KEYPAD
  595.  
  596. ;
  597.  
  598. int_9_isr    PROC    FAR
  599. ;--------------------------------------
  600. ;Entry point of the ISR
  601. ;--------------------------------------
  602. int_9_100:
  603.     STI
  604.  
  605.     PUSH    AX
  606.     PUSH    BX
  607.     PUSH    CX
  608.     PUSH    SI
  609.  
  610.     PUSH    DS
  611.  
  612. IFDEF LINK_CPP_TEST        ;Linkage different during test
  613.     MOV    CX,CS        ;since AL has "simulated" scan code
  614.     MOV    DS,CX        ;can't lose it by using AX !!
  615.         ASSUME DS:_TEXT
  616.  
  617.     MOV    CX,BIOS_DATA
  618.     MOV    DS,CX
  619.         ASSUME DS:BIOS_DATA
  620.  
  621.     MOV    AH,CH        ;we also rely on AH=0 from MOV AX,BIOS_DATA
  622. ELSE
  623.     MOV    AX,CS
  624.     MOV    DS,AX
  625. IFDEF STANDALONE_TEST
  626.         ASSUME DS:_TEXT
  627. ELSE
  628.         ASSUME DS:zcode
  629. ENDIF
  630.     DISABLE_KB
  631.     CALL    WAIT_8042_ACCEPTED    ;MUST WAIT FOR THIS TO BE ACCEPTED
  632.     STI
  633.  
  634.     MOV    AX,BIOS_DATA
  635.     MOV    DS,AX
  636.         ASSUME DS:BIOS_DATA
  637.  
  638.     IN    AL,IO_KB_DATA        ;READ THE SCAN CODE
  639. ENDIF
  640.  
  641.     MOV    BL,AL            ;SCAN CODE TO BL FOR INDEX
  642.     MOV    BH,AH            ;AH STILL 0 FROM BIOS_DATA
  643.     MOV    AH,AL            ;DUPLICATE SCAN CODE IN AH
  644.     AND    AL,NOT BREAK_CODE    
  645.  
  646.     MOV    BL,CS:JUMPTAB_INDEX [BX]
  647.     DEC    BX            ;ENTRY WAS 0 ??
  648.     JS    IGNORE_NOBEEP        ;SCAN CODE IS TOTALLY IGNORED
  649.  
  650.  
  651.     TEST    BIOS_EXTKB_SHIFT_FLAGS,PAUSE_ACTIVE
  652.     JZ    NOPAUSE            ;NOT IN PAUSE STATE
  653.  
  654.     TEST    AH,BREAK_CODE    
  655.     JNZ    NOPAUSE            ;CAN'T EXIT ON BREAK KEY
  656.     CMP    BL,EXITS_PAUSE
  657.     JNL    NOPAUSE            ;KEY DOES NOT EXIT PAUSE STATE
  658.  
  659.     AND    BIOS_EXTKB_SHIFT_FLAGS,NOT PAUSE_ACTIVE
  660.     JMP    SHORT IGNORE_NOBEEP
  661.  
  662. NOPAUSE:
  663.     MOV    CL,BIOS_KB_SHIFT_FLAGS    ;GET CURRENT SHIFT FLAGS
  664.     MOV    SI,CX
  665.     AND    SI,15            ;ISOLATE SHIFTS AND CY=0
  666.     RCR    SI,1
  667.     JNC    NO_RIGHTSH
  668.     OR    SI,1            ;RIGHT SHIFT WAS ON
  669.  
  670. NO_RIGHTSH:
  671.     SHL    SI,1
  672.     MOV    SI,CS:SHIFT_TABLES [SI]
  673.  
  674.     SHL    BX,1
  675.     XCHG    SI,BX
  676.     CALL    CS:JUMP_TAB [SI]    
  677.  
  678.     CMP    AH,BEEP_NOCODE
  679.     JAE    IGNORE_SCANCODE
  680.     CMP    AL,CTRL_INVALID
  681.     JE    IGNORE_SCANCODE
  682.  
  683. ;Have word to insert in buffer here....
  684.     MOV    CS:ALTBYTE,0
  685.     AND     BIOS_KB_EXTSTAT_1,NOT (LASTCODE_E0 OR LASTCODE_E1)
  686.  
  687. IFDEF LINK_CPP_TEST
  688.     MOV    CS:KBBUF,AX    ;STORE TO LOCAL WORD
  689. ENDIF
  690. IFDEF STANDALONE_TEST
  691.     MOV    CX,AX        ;OR STORE TO BUFFER FOR INT 16 GET
  692.     MOV    AH,5        
  693.     INT    16H
  694. ENDIF
  695.  
  696.  
  697. ; Store to debugger buffer               
  698.  
  699.                 push    ds
  700.                 mov     bx, DATA
  701.                 mov     ds, bx
  702.              ASSUME  DS:DATA
  703.                 mov     bx, buf_put             ;get buffer ptr
  704.                 mov     si, bx
  705.                 add     bx, 2                   ;advance to next position
  706.                 cmp     bx, BUF_END             ;at end?
  707.                 jne     short int_9_i200
  708.                 mov     bx, BUF_START           ;if so, wrap
  709.                 
  710. int_9_i200:
  711.                 cmp     bx, buf_put          ;buffer full?
  712.                 je      short int_9_900      ;if so, don't store char
  713.                 mov     [si], ax             ;store ascii char and scan
  714.                 mov     buf_put, bx          ;save buffer pointer
  715. int_9_900:
  716.                 pop     ds
  717.         ASSUME DS:BIOS_DATA
  718.  
  719.  
  720.  
  721.     JMP    SHORT RESET_PIC_REENABLE_KB
  722.  
  723. IGNORE_SCANCODE:
  724.     JNE    IGNORE_NOBEEP
  725.  
  726. ;If you want a beep, it goes here
  727.  
  728. IGNORE_NOBEEP:
  729.     CMP    AH,NOCODE_PICRESET
  730.     JE    PIC_RESET_OK
  731.  
  732.  
  733. RESET_PIC_REENABLE_KB:
  734. IFNDEF LINK_CPP_TEST
  735.     MOV    AL,_EOI
  736.     OUT    IO_PIC,AL
  737. ENDIF
  738.  
  739. PIC_RESET_OK:
  740. IFNDEF LINK_CPP_TEST
  741.     ENABLE_KB
  742. ENDIF
  743.  
  744.     CMP    AH,NEW_PAUSE_RQ
  745.     JNE    ISR_DONE
  746.  
  747.     MOV    AL,PAUSE_ACTIVE
  748.     OR    BIOS_EXTKB_SHIFT_FLAGS,AL
  749.     STI
  750.  
  751. ISPC:        ;Incredibly Stupid Pause Code
  752.     TEST    BIOS_EXTKB_SHIFT_FLAGS,AL
  753.     JNZ    ISPC
  754.  
  755. ISR_DONE:
  756.     POP    DS
  757.  
  758.     POP    SI
  759.     POP    CX
  760.     POP    BX
  761.     POP    AX
  762.     IRET
  763. int_9_isr    ENDP
  764.  
  765.  
  766. ;
  767. ;=================================================
  768. ;Each of these functions is called with:
  769. ;    AH = Original scancode
  770. ;    AL = Scancode with bit 7 = 0
  771. ;    CL = BIOS_KB_SHIFT_FLAGS
  772. ;    CS:BX --> Translate table based on shift status
  773. ;    DS = BIOS_DATA segment
  774. ;
  775. ;Each returns:
  776. ;    AX = Word to be added to keyboard buffer, UNLESS:
  777. ;        AH=BEEP_NOCODE
  778. ;        AH=NOCODE_PICRESET    (PIC reset by handler also !)
  779. ;        AH=NEW_PAUSE_RQ
  780. ;        AH=STORE_NOCODE, OR
  781. ;        AL=CTRL_INVALID
  782. ;=================================================
  783.  
  784.  
  785. NORM_HANDLER    PROC    NEAR
  786. ;---------------------------------------
  787. ;Would be dead-nuts simple except for stupid CAPSLOCK problem.
  788. ;
  789. ;Translated code goes to AL, scan code stays in AH
  790. ;---------------------------------------
  791.     TEST    CL,ALT_PRESSED
  792.     JNZ    XLATHI_ZEROLOW
  793.  
  794. NORM_HANDLER_NOATL:
  795.     XLAT    CS:[BX]
  796.     TEST    CL,CAPSLK_ACTIVE
  797.     JZ    CASE_OK
  798.  
  799.     TEST    CL,(LSHIFT_PRESSED OR RSHIFT_PRESSED)
  800.     MOV    CX,("A" SHL 8) OR "Z"    ;ASSUME XLATE UPPER TO LOWER
  801.     JNZ    CHECK_RECASE        ;WHAT TO DO WHEN EITHER SHIFT DOWN
  802.     MOV    CX,("a" SHL 8) OR "z"    ;ELSE XLATE LOWER TO UPPER
  803.  
  804. CHECK_RECASE:
  805.     CMP    AL,CH        ;CHECK FOR IN RANGE THAT REQUIRES XLATE
  806.     JB    CASE_OK
  807.     CMP    AL,CL
  808.     JA    CASE_OK
  809.  
  810.     XOR    AL,"a"-"A"    ;TOGGLE IT THE OTHER WAY
  811.  
  812. CASE_OK:
  813.     RET
  814. NORM_HANDLER    ENDP
  815.  
  816.  
  817. SPACE_HANDLER    PROC    NEAR
  818. ;---------------------------------------
  819. ;SpaceBar always returns 3920, irregardless of shift state
  820. ;---------------------------------------
  821.     MOV    AX,3920H
  822.     RET
  823. SPACE_HANDLER    ENDP
  824.  
  825.  
  826. SLASH_HANDLER    PROC    NEAR
  827. ;---------------------------------------
  828. ;Differences between slash on "/?" key and numpad "/"
  829. ;---------------------------------------
  830.     TEST    BIOS_KB_EXTSTAT_1,LASTCODE_E0
  831.     JZ    NORM_HANDLER
  832.  
  833.     MOV    AX,0E02FH
  834.     TEST    CL,(ALT_PRESSED OR CTRL_PRESSED)
  835.     JZ     KEYPAD_SLASHRET
  836.  
  837.     MOV    AX,9500H
  838.     TEST    CL,CTRL_PRESSED
  839.     JNZ    KEYPAD_SLASHRET
  840.  
  841.     ADD    AH,0A4H - 95H
  842.  
  843. KEYPAD_SLASHRET:
  844.     RET
  845. SLASH_HANDLER    ENDP
  846.  
  847.  
  848. PRTSC_HANDLER    PROC    NEAR
  849. ;---------------------------------------
  850. ;---------------------------------------
  851.     TEST     BIOS_KB_EXTSTAT_1,LASTCODE_E0
  852.     JNZ    PRTSC_KEYPRESS
  853.  
  854. ;Since not PrtSc, check for clear Pause state
  855.     TEST    BIOS_EXTKB_SHIFT_FLAGS,PAUSE_ACTIVE
  856.     JZ    TAB_HANDLER
  857.  
  858.     AND    BIOS_EXTKB_SHIFT_FLAGS,NOT PAUSE_ACTIVE
  859.     JMP    SHORT PRTSC_NOCODE
  860.  
  861. PRTSC_KEYPRESS:
  862.     MOV    AX,CTRL_PRSTC
  863.     TEST    CL,CTRL_PRESSED
  864.     JNZ    PRTSC_RET
  865.  
  866. ;<<<<  PRTSC HERE >>>>
  867. ;;;    INT    5
  868.  
  869. PRTSC_NOCODE:
  870.     MOV    AH,STORE_NOCODE
  871.  
  872. PRTSC_RET:
  873.     RET
  874. PRTSC_HANDLER    ENDP
  875.  
  876.  
  877. TAB_HANDLER    PROC    NEAR
  878. ;---------------------------------------
  879. ;All except Ctrl-xx versions are just like normal keys.
  880. ;
  881. ;For Ctrl, table contains the value which is to be placed in 
  882. ;the high byte; 0 is placed in the low byte (like NORM <Alt>).
  883. ;
  884. ;Codes vectored here include: TAB, keypad *-+
  885. ;---------------------------------------
  886.     TEST    CL,(ALT_PRESSED OR CTRL_PRESSED)
  887.     JNZ    XLATHI_ZEROLOW
  888.     
  889. XLAT_RET:        ;CAN JUMP HERE FOR SIMPLE XLAT AND RET
  890.     XLAT    CS:[BX]
  891.     RET
  892.     
  893. XLATHI_ZEROLOW:        ;JUMP HERE WHEN TABLE HAS HI BYTE, LOW BYTE TO = 0
  894.     XOR    AH,AH
  895. XLATHI_E0LOW:        ;JUMP HERE WHEN TABLE HAS HI BYTE, AL=LOW BYTE
  896.     XLAT    CS:[BX]
  897.     XCHG    AH,AL
  898.     RET
  899. TAB_HANDLER    ENDP
  900.  
  901.  
  902. FNKEY_HANDLER    PROC    NEAR
  903. ;---------------------------------------
  904. ;For function keys, the table contains the value which is to be
  905. ;ADDED to the scan code.
  906. ;
  907. ;Key result is a zero in low byte; translated scancode in high byte
  908. ;---------------------------------------
  909.     XLAT    CS:[BX]
  910.     ADD    AH,AL
  911.     XOR    AL,AL
  912.     RET
  913. FNKEY_HANDLER    ENDP
  914.  
  915.  
  916. NUMPAD_HANDLER    PROC    NEAR
  917. ;---------------------------------------
  918. ;The numeric keypad handling gets a little tricky ...
  919. ;
  920. ;For Ctrl and Alt, the tables contain the value which is 
  921. ;to be placed in the high byte; a 00 OR E0 is placed in the low byte.
  922. ;
  923. ;This routine DOES NOT update the INS_ACTIVE and INS_PRESSED flags !!
  924. ;---------------------------------------
  925.     MOV    CH,BIOS_KB_EXTSTAT_1
  926.     TEST    CL,ALT_PRESSED        ;TEST ALT PRESSED
  927.     JNZ    ALT_NUMPAD_ENTRY    ;ALT ENTRIES ARE DIFFERENT
  928.  
  929. ;NOT <ALT> ...
  930.     TEST    CH,LASTCODE_E0        ;SEPARATE SET OF CURSOR KEYS ??
  931.     JZ    DUAL_NUMPAD_KEY        ;NO -- ONE OF OLD DUAL/KEYS
  932.  
  933.     MOV    AH,0E0H
  934.     CMP    BX,OFFSET SHIFTED_XLAT_TAB ;<SHIFT> TABLE WILL GIVE US 0-9 !
  935.     JNZ    XLATHI_E0LOW        ;IT'S OK -- BX HAS CORRECT TABLE
  936.  
  937.     MOV    BX,OFFSET UNSHIFTED_XLAT_TAB
  938.     JMP    XLATHI_E0LOW
  939.  
  940.  
  941. DUAL_NUMPAD_KEY:
  942.     TEST    CL,CTRL_PRESSED
  943.     JNZ    XLATHI_ZEROLOW        ;THESE ALL GET ZERO IN LOW BYTE
  944.  
  945.     MOV    BX,OFFSET SHIFTED_XLAT_TAB
  946.     XLAT    CS:[BX]
  947.     MOV    SI,AX            ;SI IS VALUE IF "SHIFTED"
  948.     XOR    AL,AL            ;AX IS VALUE IF NOT
  949.  
  950.     TEST    CL,NUMLK_ACTIVE
  951.     JZ    NUMPAD_TOGOFF
  952.     XCHG    AX,SI            ;REVERSE WHEN NUMLOCK ACTIVE
  953.  
  954. NUMPAD_TOGOFF:
  955.     TEST    CL,(LSHIFT_PRESSED OR RSHIFT_PRESSED)
  956.     JZ    NUMPAD_SHIFTNORM
  957.     MOV    AX,SI
  958.     
  959. NUMPAD_SHIFTNORM:
  960.     RET
  961.  
  962.  
  963. ALT_NUMPAD_ENTRY:
  964.     CMP    AH,53H            ;DELETE KEY MAKE ??
  965.     JNZ    NO_REBOOT
  966.     TEST    CL,CTRL_PRESSED        ;CTRL PRESSED ALSO ??
  967.     JZ    NO_REBOOT
  968.  
  969. ;<<<<  CTRL-ALT-DELETE HERE >>>>
  970.     MOV    AH,STORE_NOCODE
  971.     RET
  972.  
  973. NO_REBOOT:
  974.     TEST    CH,LASTCODE_E0        ;SEPARATE SET OF CURSOR KEYS ??
  975.     JNZ    XLATHI_ZEROLOW        ;THESE GET ZERO IN LOW BYTE
  976.     
  977.     MOV    AH,STORE_NOCODE        ;RETURN CODE
  978.     MOV    BX,OFFSET SHIFTED_XLAT_TAB ;XLAT TO 0-9
  979.     XLAT    CS:[BX]
  980.     SUB    AL,"0"
  981.     JC    NUMPAD_NODIGIT
  982.     CMP    AL,9
  983.     JA    NUMPAD_NODIGIT
  984.  
  985.     XCHG    AH,CS:ALTBYTE
  986.     SHL    AH,1
  987.     ADD    AL,AH            ;ORIGINAL * 2 + NEW
  988.     SHL    AH,2             ;ORIGINAL * 8
  989.     ADD    AH,AL
  990.     XCHG    CS:ALTBYTE,AH        ;STORE NEW VALUE, GET BACK RETURN CODE
  991.     
  992. NUMPAD_NODIGIT:
  993.     RET
  994. NUMPAD_HANDLER    ENDP
  995.  
  996.  
  997.  
  998. TWOPART_HANDLER    PROC    NEAR
  999. ;---------------------------------------
  1000. ;Vectored here because scan code was E0 or E1.
  1001. ;
  1002. ;Set proper bits in 'BIOS_KB_EXTSTAT_1'
  1003. ;
  1004. ;Return STORE_NOCODE so bogus code not saved to buffer.
  1005. ;---------------------------------------
  1006.     MOV    AL,LASTCODE_E1
  1007.     CMP    AH,0E1H
  1008.     JZ    SET_LASTCODE_FLAG
  1009.     MOV    AL,LASTCODE_E0
  1010.  
  1011. SET_LASTCODE_FLAG:
  1012.     OR     BIOS_KB_EXTSTAT_1,AL    ;TURN ON LAST CODE FLAG
  1013.     XOR    AL,3
  1014.     NOT    AL
  1015.     AND     BIOS_KB_EXTSTAT_1,AL    ;TURN OFF OPPOSITE ONE
  1016.  
  1017.     MOV    AH,STORE_NOCODE
  1018.     RET
  1019. TWOPART_HANDLER    ENDP
  1020.  
  1021.  
  1022.  
  1023. TOGGLEKEY_HANDLER    PROC    NEAR
  1024. ;---------------------------------------
  1025. ;The toggle keys require setting/clearing bits, and perhaps 
  1026. ;updating the keyboard LED indicators.
  1027. ;
  1028. ;The three keys which vector here are: CAPSLOCK, NUMLOCK, SCROLL-LOCK
  1029. ;---------------------------------------
  1030.     TEST    BIOS_EXTKB_SHIFT_FLAGS,PAUSE_ACTIVE
  1031.     JZ    TOGGLE_NO_PAUSE
  1032.     CMP    AL,45
  1033.     JZ    TOGGLE_NO_PAUSE        ;CAN'T EXIT PAUSE W/NUM LOCK KEY
  1034.  
  1035.     TEST    CL,CTRL_PRESSED
  1036.     JZ    TOGGLE_NO_PAUSE        ;ONLY CTRL-TOGGLE EXITS PAUSE
  1037.  
  1038.     AND    BIOS_EXTKB_SHIFT_FLAGS,NOT PAUSE_ACTIVE
  1039.     MOV    AH,STORE_NOCODE
  1040.     RET
  1041.  
  1042.  
  1043. TOGGLE_NO_PAUSE:
  1044.     XLAT    CS:[BX]            ;BITS FOR BIOS_KB_SHIFT_FLAGS
  1045.     CMP    AL,PAUSE_ACTIVE
  1046.     JNE    NO_TOGGLE_PAUSE
  1047.  
  1048. ;PAUSE REQUEST HERE
  1049.     TEST    CL,AL        ;ALREADY PAUSE ???
  1050.     JNZ    NEW_SHIFT_STATE2  ;C'MON ...
  1051.  
  1052.     AND     BIOS_KB_EXTSTAT_1,NOT (LASTCODE_E0 OR LASTCODE_E1)
  1053.     MOV    AH,NEW_PAUSE_RQ
  1054.     RET
  1055.     
  1056.  
  1057. NO_TOGGLE_PAUSE:
  1058.     TEST    AH,BREAK_CODE
  1059.     JNZ    TOGGLE_BREAK
  1060.  
  1061.     CMP    AH,46H            ;SCROLL-LOCK KEY MAKE ??
  1062.     JNZ    NO_CTRLBREAK
  1063.     TEST    CL,CTRL_PRESSED        ;CTRL PRESSED ALSO ??
  1064.     JZ    NO_CTRLBREAK
  1065.  
  1066. ;<<<<  CTRL-BREAK HERE >>>>
  1067. ;;    INT    1BH
  1068.     MOV    AH,STORE_NOCODE
  1069.     RET
  1070.     
  1071. NO_CTRLBREAK:
  1072.     OR    BIOS_EXTKB_SHIFT_FLAGS,AL    ;MARK IT'S PRESSED
  1073.  
  1074.     XOR    CL,AL        ;TOGGLE STATE ON MAKE ONLY
  1075.     MOV    BIOS_KB_SHIFT_FLAGS,CL    ;SAVE NEW STATE
  1076.  
  1077. IFNDEF LINK_CPP_TEST
  1078.     MOV    AL,_EOI
  1079.     OUT    IO_PIC,AL
  1080. ENDIF
  1081.     CALL    NEW_LEDS
  1082.     AND     BIOS_KB_EXTSTAT_1,NOT (LASTCODE_E0 OR LASTCODE_E1)
  1083.     MOV    AH,NOCODE_PICRESET
  1084.     RET
  1085.  
  1086. TOGGLE_BREAK:
  1087.     NOT    AL
  1088.     AND    BIOS_EXTKB_SHIFT_FLAGS,AL    ;MARK NO LONGER PRESSED
  1089.     JMP     SHORT NEW_SHIFT_STATE
  1090. TOGGLEKEY_HANDLER    ENDP
  1091.  
  1092.  
  1093. SHIFTKEY_HANDLER     PROC    NEAR
  1094. ;---------------------------------------
  1095. ;The shift keys require setting/clearing bits. 
  1096. ;
  1097. ;When <Alt> key is released, have to check for accumed ASCII 
  1098. ;value entered via numeric keypad.
  1099. ;
  1100. ;There are actually six keys which vector here:
  1101. ;   Left/Right CTRL, Left/Right ALT, and Left/Right SHIFT
  1102. ;---------------------------------------
  1103.     XLAT    CS:[BX]            ;BITS FOR BIOS_KB_SHIFT_FLAGS
  1104.  
  1105.     XOR    CH,CH
  1106.     TEST     BIOS_KB_EXTSTAT_1,LASTCODE_E0
  1107.     JZ      SHIFT_MASKS_SET    ;LAST NOT E0, IF CTRL/ALT, WAS RIGHT KEY
  1108.  
  1109.     CMP    AL,CTRL_PRESSED
  1110.     JZ    SHIFT_ISCTRL
  1111.     CMP    AL,ALT_PRESSED
  1112.     JZ    SHIFT_MASKS_SET    ;WAS L/R SHIFT, CH=0
  1113.  
  1114.     INC    CH        ;LALT_PRESSED = 2
  1115.  
  1116. SHIFT_ISCTRL:
  1117.     INC    CH        ;LCTRL_PRESSED = 1
  1118.  
  1119. SHIFT_MASKS_SET:
  1120.     TEST    AH,BREAK_CODE
  1121.     JZ    SHIFTMAKE
  1122.  
  1123. ;Shift key released here ...
  1124.     CMP    AL,ALT_PRESSED
  1125.     PUSHF
  1126.  
  1127.     NOT    AL
  1128.     AND    CL,AL
  1129.     NOT    CH
  1130.     AND    BIOS_EXTKB_SHIFT_FLAGS,CH
  1131.     CALL     SHORT NEW_SHIFT_STATE
  1132.  
  1133.     POPF
  1134.     JNZ    SHIFTBRK_NONALT
  1135.  
  1136.     XOR    AX,AX
  1137.     XCHG    AL,CS:ALTBYTE
  1138.     CMP    AH,AL            ;AH=0, AL=Byte accumed
  1139.     JZ    ALTBRK_NO_ASCIIBYTE
  1140.  
  1141. SHIFTBRK_NONALT:
  1142.     RET
  1143.  
  1144.  
  1145. ;Shift key pressed here ...
  1146. SHIFTMAKE:
  1147.     OR    CL,AL
  1148.     OR    BIOS_EXTKB_SHIFT_FLAGS,CH
  1149.  
  1150. NEW_SHIFT_STATE:
  1151.     MOV    BIOS_KB_SHIFT_FLAGS,CL
  1152. NEW_SHIFT_STATE2:
  1153.     AND     BIOS_KB_EXTSTAT_1,NOT (LASTCODE_E0 OR LASTCODE_E1)
  1154.  
  1155. ALTBRK_NO_ASCIIBYTE:
  1156.     MOV    AH,STORE_NOCODE
  1157.     RET
  1158. SHIFTKEY_HANDLER     ENDP
  1159.  
  1160.  
  1161. ACK_HANDLER    PROC    NEAR
  1162. ;---------------------------------------
  1163. ;Set bit in control word that we received ACK code
  1164. ;---------------------------------------
  1165.     MOV    AL,ACK_FROM8042
  1166.     JMP    SHORT KB_CMD_RX
  1167. ACK_HANDLER    ENDP
  1168.  
  1169.  
  1170. RESEND_HANDLER    PROC    NEAR
  1171. ;---------------------------------------
  1172. ;Set bit in control word that we received RESEND code
  1173. ;---------------------------------------
  1174.     MOV    AL,RESEND_FROM8042
  1175.  
  1176. KB_CMD_RX:
  1177.     OR    BIOS_KB_EXTSTAT_2,AL
  1178.     AND     BIOS_KB_EXTSTAT_1,NOT (LASTCODE_E0 OR LASTCODE_E1)
  1179.  
  1180.     MOV    AH,STORE_NOCODE
  1181.     RET
  1182. RESEND_HANDLER    ENDP
  1183.  
  1184.  
  1185. OVERRUN_HANDLER    PROC    NEAR
  1186. ;---------------------------------------
  1187. ;---------------------------------------
  1188.     AND     BIOS_KB_EXTSTAT_1,NOT (LASTCODE_E0 OR LASTCODE_E1)
  1189.  
  1190. ;Fall into SYS_HANDLER since it's a dummy
  1191. ;    MOV    AH,BEEP_NOCODE
  1192. ;    RET
  1193. OVERRUN_HANDLER    ENDP
  1194.  
  1195.  
  1196. SYS_HANDLER    PROC    NEAR
  1197. ;---------------------------------------
  1198. ;---------------------------------------
  1199.     MOV    AH,BEEP_NOCODE
  1200.      RET
  1201. SYS_HANDLER    ENDP
  1202.  
  1203.  
  1204.  
  1205. ;
  1206. WAIT_8042_ACCEPTED    PROC    NEAR
  1207. ;---------------------------------------
  1208. ;This routine waits until the 8042 has received the command byte
  1209. ;---------------------------------------
  1210.     CALL    WAIT_ACCEPTED
  1211.     JNZ    RX_BY_8042
  1212.     CLI    
  1213.     
  1214. WAIT_ACCEPTED:
  1215.     XOR    CX,CX
  1216.  
  1217. WAIT_8042_BYTE:
  1218.     IN    AL,IO_KB_8042
  1219.     TEST    AL,_8042_IBUF_FULL
  1220.     LOOPNZ    WAIT_8042_BYTE
  1221.  
  1222. RX_BY_8042:
  1223.     RET
  1224. WAIT_8042_ACCEPTED    ENDP
  1225.  
  1226.  
  1227. NEW_LEDS    PROC    NEAR
  1228. ;---------------------------------------
  1229. ;Build the new LED byte and sends the commands to 8042 to have
  1230. ;the indicators displayed.
  1231. ;
  1232. ;Entry:
  1233. ;    CL = BIOS_KB_SHIFT_FLAGS
  1234. ;---------------------------------------
  1235.     PUSH    CX
  1236.  
  1237.     CLI
  1238.     BTS    BIOS_KB_EXTSTAT_2,6    ;BIT 6=LEDUPD_INPROG
  1239.     JC    LEDS_GOOD
  1240.  
  1241.     SHR    CL,4            ;MOVE ACTIVE BITS TO LOW NYBBLE
  1242.     MOV    CH,(CAPSLK_LED OR NUMLK_LED OR SCRLK_LED)
  1243.     AND    CL,CH
  1244.  
  1245.     PUSH    CX            ;SAVE INDICATORS
  1246.  
  1247.     NOT    CH
  1248.     AND    CH,BIOS_KB_EXTSTAT_2    ;INDICATORS OFF
  1249.     OR    CH,CL            ;NEW INDICATORS ON
  1250.     MOV    BIOS_KB_EXTSTAT_2,CH    ;RESAVE
  1251.  
  1252.     STI
  1253.     ENABLE_KB
  1254.     MOV    AH,KB_8042_NEWLED
  1255.     CALL    SEND_8042_COMMAND
  1256.  
  1257.     POP    CX            ;RESTORE INDICATORS
  1258.     JC    KB_CRASHED
  1259.     
  1260.     MOV    AH,CL            ;INDICATORS TO AH
  1261.     CALL    SEND_8042_COMMAND    ;SEND THE BYTE
  1262.     JNC    NEW_LEDS_SET        ;SUCCESSFUL
  1263.  
  1264.  
  1265. ;Something WRONG with 8042 interface .. clear and re-enable
  1266. KB_CRASHED:
  1267.     MOV    AL,KB_8042_CLR_REENABLE
  1268.     CALL    SEND_8042_COMMAND
  1269.  
  1270. NEW_LEDS_SET:
  1271.     AND    BIOS_KB_EXTSTAT_2,NOT LEDUPD_INPROG    ;CLEAR UPDATE FLAG
  1272.  
  1273. LEDS_GOOD:
  1274.     STI
  1275.  
  1276.     POP    CX
  1277.     RET
  1278. NEW_LEDS    ENDP
  1279.  
  1280.  
  1281. SEND_8042_COMMAND    PROC    NEAR
  1282. ;---------------------------------------
  1283. ;Sends command to 8042, and waits for either ACK or RESEND 
  1284. ;to be received.  
  1285. ;
  1286. ;Up to three retries will be attempted if RESEND is received.
  1287. ;
  1288. ;Entry:
  1289. ;    AH = byte to output
  1290. ;
  1291. ;Returns:
  1292. ;    CY=1 if ACK not received
  1293. ;    Interrupts are turned OFF on exit !
  1294. ;---------------------------------------
  1295.     PUSH    DX
  1296.     MOV    DL,3
  1297.  
  1298. RESEND_8042_CMD:
  1299.     AND    BIOS_KB_EXTSTAT_2, NOT (RESEND_FROM8042 OR ACK_FROM8042)
  1300.  
  1301.     CALL    WAIT_8042_ACCEPTED
  1302.     MOV    AL,AH
  1303.     OUT    IO_KB_DATA,AL        
  1304.     STI
  1305.  
  1306.     XOR    CX,CX
  1307.  
  1308. WAIT_CMD_ACCEPT:
  1309.     TEST    BIOS_KB_EXTSTAT_2,(RESEND_FROM8042 OR ACK_FROM8042)
  1310.     LOOPZ    WAIT_CMD_ACCEPT
  1311.     JZ    CMD_FAILED
  1312.  
  1313.     BTS    BIOS_KB_EXTSTAT_2,4    ;BIT 4 = ACK_FROM8042
  1314.     JC    SEND_CMD_RET        ;ACK RECEIVED, CMC WILL MAKE CY=0
  1315.  
  1316. CMD_FAILED:    ;NO RESPONSE OR 'RESEND'
  1317.     DEC    DL
  1318.     JNZ    RESEND_8042_CMD        
  1319.                     ;ELSE DL=0, CY=0, CMC WILL MAKE 1
  1320. SEND_CMD_RET:
  1321.     CMC
  1322.  
  1323.     POP    DX
  1324.     RET            ;CY=0 FROM 'TEST'
  1325. SEND_8042_COMMAND    ENDP
  1326.  
  1327.  
  1328. IFDEF LINK_CPP_TEST
  1329. _TEXT            ends
  1330. ELSE
  1331. IFDEF STANDALONE_TEST
  1332. _TEXT            ends
  1333. ELSE
  1334. zcode            ends
  1335. ENDIF
  1336. ENDIF
  1337.  
  1338. END
  1339.  
  1340.  
  1341.